/*++

Copyright (c) 2007  Microsoft Corporation 

Filename: 

    ReportDlg.cs

Abstract: 

    A form showing the result of Monitoring
*/

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;
using System.Runtime.InteropServices;
using Visio = Microsoft.Office.Interop.Visio;
using Excel = Microsoft.Office.Interop.Excel;
using System.Globalization;

namespace NRTMAddIn
{
    /// <summary>
    /// Summary description for ReportDlg.
    /// </summary>
    public class ReportDlg : BaseForm
    {

        #region fields

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private DataTable dtDiskData;

        private DataGridView DataGridViewReport;

        private Document m_NRTMDocument;
        delegate void AddRowsCallback(String[] rows);
        delegate void ClearGridCallback();

        Excel.Application ExcelReportFile;
        Excel.Workbook WorkBook;
        Excel.Worksheet WorkSheet;

        private SaveFileDialog saveFileDialog;
        private DataGridViewTextBoxColumn txtboxNetwork;
        private DataGridViewTextBoxColumn txtboxIP;
        private DataGridViewTextBoxColumn txtboxDisK;
        private DataGridViewTextBoxColumn txtboxTotal;
        private DataGridViewTextBoxColumn txtboxFree;
        private DataGridViewTextBoxColumn txtboxUsed;
        private DataGridViewTextBoxColumn txtboxFileSys;
        private DataGridViewTextBoxColumn txtboxType;
        private DataGridViewTextBoxColumn txtboxState;
               
        
        #endregion

        #region construction / destruction

        /// <summary>
        /// Default Constructor.
        /// </summary>
        public ReportDlg()
        {
            InitializeComponent();           
        }


        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        #endregion

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ReportDlg));
            this.DataGridViewReport = new System.Windows.Forms.DataGridView();
            this.txtboxNetwork = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxIP = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxDisK = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxTotal = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxFree = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxUsed = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxFileSys = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxType = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.txtboxState = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
            ((System.ComponentModel.ISupportInitialize)(this.DataGridViewReport)).BeginInit();
            this.SuspendLayout();
            // 
            // DataGridViewReport
            // 
            this.DataGridViewReport.AllowUserToAddRows = false;
            this.DataGridViewReport.AllowUserToDeleteRows = false;
            this.DataGridViewReport.AllowUserToOrderColumns = true;
            this.DataGridViewReport.AllowUserToResizeRows = false;
            resources.ApplyResources(this.DataGridViewReport, "DataGridViewReport");
            this.DataGridViewReport.BackgroundColor = System.Drawing.SystemColors.Control;
            this.DataGridViewReport.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.txtboxNetwork,
            this.txtboxIP,
            this.txtboxDisK,
            this.txtboxTotal,
            this.txtboxFree,
            this.txtboxUsed,
            this.txtboxFileSys,
            this.txtboxType,
            this.txtboxState});
            this.DataGridViewReport.Name = "DataGridViewReport";
            this.DataGridViewReport.ReadOnly = true;
            this.DataGridViewReport.RowHeadersVisible = false;
            // 
            // txtboxNetwork
            // 
            resources.ApplyResources(this.txtboxNetwork, "txtboxNetwork");
            this.txtboxNetwork.Name = "txtboxNetwork";
            this.txtboxNetwork.ReadOnly = true;
            // 
            // txtboxIP
            // 
            resources.ApplyResources(this.txtboxIP, "txtboxIP");
            this.txtboxIP.Name = "txtboxIP";
            this.txtboxIP.ReadOnly = true;
            // 
            // txtboxDisK
            // 
            resources.ApplyResources(this.txtboxDisK, "txtboxDisK");
            this.txtboxDisK.Name = "txtboxDisK";
            this.txtboxDisK.ReadOnly = true;
            // 
            // txtboxTotal
            // 
            resources.ApplyResources(this.txtboxTotal, "txtboxTotal");
            this.txtboxTotal.Name = "txtboxTotal";
            this.txtboxTotal.ReadOnly = true;
            // 
            // txtboxFree
            // 
            resources.ApplyResources(this.txtboxFree, "txtboxFree");
            this.txtboxFree.Name = "txtboxFree";
            this.txtboxFree.ReadOnly = true;
            // 
            // txtboxUsed
            // 
            resources.ApplyResources(this.txtboxUsed, "txtboxUsed");
            this.txtboxUsed.Name = "txtboxUsed";
            this.txtboxUsed.ReadOnly = true;
            // 
            // txtboxFileSys
            // 
            resources.ApplyResources(this.txtboxFileSys, "txtboxFileSys");
            this.txtboxFileSys.Name = "txtboxFileSys";
            this.txtboxFileSys.ReadOnly = true;
            // 
            // txtboxType
            // 
            resources.ApplyResources(this.txtboxType, "txtboxType");
            this.txtboxType.Name = "txtboxType";
            this.txtboxType.ReadOnly = true;
            // 
            // txtboxState
            // 
            resources.ApplyResources(this.txtboxState, "txtboxState");
            this.txtboxState.Name = "txtboxState";
            this.txtboxState.ReadOnly = true;
            // 
            // ReportDlg
            // 
            resources.ApplyResources(this, "$this");
            this.Controls.Add(this.DataGridViewReport);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "ReportDlg";
            ((System.ComponentModel.ISupportInitialize)(this.DataGridViewReport)).EndInit();
            this.ResumeLayout(false);

        }
        #endregion

        #region methods

        /// <summary>
        /// Show ReportData in ReportDataGridView
        /// </summary>
        internal void ShowGridData()
        {
            string notAvail = string.Empty;

            try
            {
                notAvail = Global.GetResourceString("NRTM_DataGrid_Null");

                //Clear current data if exist
                ClearDataGrid();

                //Get disk details table to temp datatable 
                dtDiskData = m_NRTMDocument.MonitorDB.DtDiskDetails;

                string[] strArray = new string[dtDiskData.Columns.Count + 1];

                //Iterate through the rows of temp datatable  
                foreach (DataRow dtDiskRow in dtDiskData.Rows)
                {
                    //Get server name 
                    string server = Convert.ToString(dtDiskRow.ItemArray[0], CultureInfo.InvariantCulture);
                    
                    //Server name in a string array
                    strArray[0] = server;

                    //Build string array as datagridview rows
                    for (int arrayIndex = 1; arrayIndex < strArray.Length; arrayIndex++)
                    {
                        //Get IP Address from DtMachines table
                        if (arrayIndex == 1)
                        {
                            //Filter expression as Server name
                            string strfilter = "ServerName=" + "\'" + server + "\'";
                            DataRow[] dRow = m_NRTMDocument.MonitorDB.DtMachines.Select(strfilter);
                            //Get IP address from the Machine table
                            if (dRow.Length != 0 && dRow[0].ItemArray[1].ToString().Trim().CompareTo(string.Empty) != 0)
                            {
                                strArray[arrayIndex] = dRow[0].ItemArray[1].ToString();
                            }
                            else
                            {
                                //Ip address not available
                                strArray[arrayIndex] = notAvail;
                            }
                        }
                        //Calculate used space
                        else if (arrayIndex == 5)
                        {
                            if (strArray[4] == notAvail || strArray[3] == notAvail)
                            {
                                //If free space not available
                                strArray[arrayIndex] = notAvail;
                            }
                            else
                            {
                                //Calculate and store the used space from total & free space
                                strArray[arrayIndex] = Convert.ToString(Convert.ToInt32(strArray[3], CultureInfo.InvariantCulture) - Convert.ToInt32(strArray[4], CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
                            }
                        }
                        //Get type and filesystem
                        else if (arrayIndex == 6 || arrayIndex == 7)
                        {
                            if (dtDiskRow.ItemArray[arrayIndex - 2] == DBNull.Value)
                            {
                                //Data not available
                                strArray[arrayIndex] = notAvail;
                            }
                            else
                            {
                                strArray[arrayIndex] = dtDiskRow.ItemArray[arrayIndex - 2].ToString();
                            }
                        }
                        else
                        {
                            if (dtDiskRow.ItemArray[arrayIndex - 1] == DBNull.Value)
                            {
                                //Data not available
                                strArray[arrayIndex] = notAvail;
                            }
                            else
                            {

                                strArray[arrayIndex] = dtDiskRow.ItemArray[arrayIndex - 1].ToString();
                            }
                        }
                    }
                    //Adds data row to grid
                    AddDataToGrid(strArray);
                }
            }
            catch (System.Threading.ThreadAbortException)
            {
                //Ignore thread abort exception
            }
            catch (NrtmException ex)
            {
                //Exception from sub function. Pass on to entry point
                throw new NrtmException("Show Report", ex.InnerException);
            }
            catch (Exception ex)
            {
                //Exception from current function
                throw new NrtmException("Show Report", ex);
            }
        }

        /// <summary>
        /// Export DataGridView Results To MSExcel
        /// </summary>
        internal void ExportToExcel()
        {
            try
            {
                if (!Global.ExcelInstalled())
                {
                    MessageBox.Show(Global.GetResourceString("Excel_Install"),
                        Global.GetResourceString("ExcelReport_FileDialog_Title"),
                        MessageBoxButtons.OK, MessageBoxIcon.Error,
                        MessageBoxDefaultButton.Button1);
                    return;
                }

                //Format datetime to add in report name
                DateTime dateTime = DateTime.Now;
                CultureInfo culture = new CultureInfo("ur-PK");
                string CurrentDateTime = Convert.ToString(dateTime, culture).Replace(':', '-').Replace('/', '-');

                //Get a excel file name from user
                this.saveFileDialog.FileName = Global.GetResourceString("NRTM_ReportName") + CurrentDateTime;
                this.saveFileDialog.Title = Global.GetResourceString("ExcelReport_FileDialog_Title");
                this.saveFileDialog.InitialDirectory = Global.AppPath();
                this.saveFileDialog.Filter = Global.GetResourceString("Excel_FileDialog_Filter");
                DialogResult saveReport = this.saveFileDialog.ShowDialog();
                if (saveReport != DialogResult.OK)
                {
                    return;
                }


                //Create Excel application object
                ExcelReportFile = new Excel.Application();

                //Add workbook to an excel object 
                WorkBook = (Excel.Workbook)ExcelReportFile.Workbooks.Add("workbook");

                //Get the active worksheet
                WorkSheet = (Excel.Worksheet)WorkBook.ActiveSheet;

                int ColCtr = 1;

                //Add table headers going cell by cell.
                foreach (DataGridViewColumn dgvColm in DataGridViewReport.Columns)
                {
                    WorkSheet.Cells[1, ColCtr] = dgvColm.HeaderText;
                    ColCtr++;
                }

                //Format header columns 
                WorkSheet.get_Range("A1:I1", Missing.Value).Font.Bold = true;
                WorkSheet.get_Range("A1", "I1").ColumnWidth = 15;
                WorkSheet.get_Range("A1", "I1").HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                WorkSheet.get_Range("1:" + (DataGridViewReport.Rows.Count + 1) + "", Missing.Value).WrapText = true;
                WorkSheet.get_Range("2:" + (DataGridViewReport.Rows.Count + 1) + "", Missing.Value).HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft;

                //Get data into excel through datagrid going cell by cell
                for (int RowIndex = 0; RowIndex < DataGridViewReport.Rows.Count; RowIndex++)
                {
                    DataGridViewRow dataRow = DataGridViewReport.Rows[RowIndex];
                    for (int ColIndex = 0; ColIndex < DataGridViewReport.Columns.Count; ColIndex++)
                    {
                        WorkSheet.Cells[RowIndex + 2, ColIndex + 1] = (string)dataRow.Cells[ColIndex].Value;
                    }
                }

                //Save report as excel  
                switch (saveFileDialog.FilterIndex)
                {
                    case 1:
                        //As .xslx
                        WorkBook.SaveAs(this.saveFileDialog.FileName,
                        Excel.XlFileFormat.xlOpenXMLWorkbook, Missing.Value, Missing.Value,
                        false, false, Excel.XlSaveAsAccessMode.xlNoChange,
                        Missing.Value, true, Missing.Value, Missing.Value, true);
                        break;

                    case 2:
                        //As .xsl
                        WorkBook.SaveAs(this.saveFileDialog.FileName,
                        Excel.XlFileFormat.xlTemplate, Missing.Value, Missing.Value,
                        false, false, Excel.XlSaveAsAccessMode.xlNoChange,
                        Missing.Value, true, Missing.Value, Missing.Value, true);
                        break;
                }                              
            }
            catch (System.Threading.ThreadAbortException)
            {
                //Ignore thread abort exception
            }
            catch (NrtmException ex)
            {
                //Exception from sub function. Pass on to entry point
                throw new NrtmException("Export report to excel", ex.InnerException);
            }
            catch (Exception ex)
            {
                //Exception from current function
                throw new NrtmException("Export report to excel", ex);
            }
            finally
            {
                if (ExcelReportFile != null)
                {
                    //Close excel instance
                    if (WorkBook != null)
                    {
                        WorkBook.Close(false, "", false);                        
                    }
                                        
                    ExcelReportFile.Workbooks.Close();
                    ExcelReportFile.Quit();
                    
                    //Release excel objects
                    Marshal.ReleaseComObject(WorkSheet);
                    Marshal.ReleaseComObject(WorkBook);
                    Marshal.ReleaseComObject(ExcelReportFile);                                      

                    //Call Garbage Collector
                    GC.Collect();
                    //GC.WaitForPendingFinalizers();

                    WorkBook = null;
                    ExcelReportFile = null;
                }
            }
        }

        /// <summary>
        /// Clear grid in a thread safe manner
        /// </summary>
        /// <param name="rows"></param>
        private void ClearDataGrid()
        {
            //Make code thread safe
            if (DataGridViewReport.InvokeRequired)
            {
                ClearGridCallback clearGrid = new ClearGridCallback(ClearDataGrid);
                this.Invoke(clearGrid);
            }
            else
            {
                DataGridViewReport.Rows.Clear();
            }
        }

        /// <summary>
        /// Get data row to grid in a thread safe manner
        /// </summary>
        /// <param name="rows"></param>
        private void AddDataToGrid(String[] rows)
        {
            //Make code thread safe
            if (DataGridViewReport.InvokeRequired)
            {
                AddRowsCallback addrows = new AddRowsCallback(AddDataToGrid);
                this.Invoke(addrows, new object[] { rows });
            }
            else
            {
                DataGridViewReport.Rows.Add(rows);
            }
        }

        #endregion

        #region properties

        /// <summary>
        ///  Gets or sets the NRTM Document object that this dialog is loaded for.
        /// </summary>
        internal Document NRTMDocument
        {
            get { return m_NRTMDocument; }

            set { m_NRTMDocument = value; }
        }

        #endregion

    }
}
